import React from 'react';
import { StyleSheet, ScrollView, View, Text, Image, TouchableOpacity } from 'react-native';
import PropTypes from 'prop-types';
import RNRestart from 'react-native-restart'



export default class ErrorBoundary extends React.Component {

    static propTypes = {
        // 自定义降级后的 UI
        errorPage: PropTypes.element
    };
    constructor(props) {
        super(props);
        this.state = {
            hasError: false,
            errMsg: ''
        };
        global.ErrorUtils.setGlobalHandler(e => {
            /* 异常处理逻辑 */
            console.log('%c ErrorUtils.setGlobalHandler处理异常', 'font-size:12px;color:#ff0000');
            this.reportError(e, '全局捕获异常');
        });
        // require('promise/setimmediate/rejection-tracking').enable({
        //     allRejections: true,
        //     onUnhandled: (id, error = {}) => {
        //         let message;
        //         let stack;

        //         const stringValue = Object.prototype.toString.call(error);
        //         if (stringValue === '[object Error]') {
        //             message = Error.prototype.toString.call(error);
        //             stack = error.stack;
        //         } else {
        //             /* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses
        //    * an error found when Flow v0.54 was deployed. To see the error delete
        //    * this comment and run Flow. */
        //             message = require('pretty-format')(error);
        //         }

        //         const warning =
        //             `Possible Unhandled Promise Rejection (id: ${id}):\n` +
        //             `${message}\n` +
        //             (stack == null ? '' : stack);
        //         console.warn(warning);
        //         // 更新 state 使下一次渲染能够显示降级后的 UI
        //         this.setState({ hasError: true, errMsg: message });
        //         this.reportError(new Error(message));
        //     },
        //     onHandled: id => {
        //         const warning =
        //             `Promise Rejection Handled (id: ${id})\n` +
        //             'This means you can ignore any previous messages of the form ' +
        //             `"Possible Unhandled Promise Rejection (id: ${id}):"`;
        //         console.warn(warning);
        //     }
        // });
    }

    componentDidCatch(error, errorInfo) {
        console.log('错误边界捕获到错误了',error);
        this.reportError(error, '错误边界捕获异常');
    }

    reportError = (error, where) => {
        let msg = `${where} \n当前页面: ${global.currentRouteName || '未知'}\n错误信息: ${error.message}`;
        this.setState({ hasError: true, errMsg: msg });

        console.log('上报错误:', msg);

    };

    render() {
        if (this.state.hasError) {
            const { errMsg } = this.state;
            return this.props.errorPage ? this.props.errorPage : <CommonErrorUI errorMsg={errMsg} />;
        }

        return this.props.children;
    }
}

export class CommonErrorUI extends React.Component {
    static propTypes = {
        // 自定义降级后的 UI
        errorMsg: PropTypes.string
    };
    constructor(props) {
        super(props);
        this.state = {};
    }
    goBack = () => {
        // navigatorRef.goBack();
    };
    restart = () => {
        // NativeUtil.showSplash();
        RNRestart.restart();
    };

    render() {
        const { showErrorMsg } = this.state;
        const { errorMsg } = this.props;
        return (
            <ScrollView style={styles.scrlview} contentContainerStyle={styles.sclcontent}>
                <View style={styles.content}>
                    <Image style={styles.erricon} source={require('../images/no_device.png')} />
                    <Text
                        style={styles.title}
                        onLongPress={() => {
                            this.setState({ showErrorMsg: !showErrorMsg });
                        }}
                    >
                        糟糕, App崩溃了
                    </Text>
                    <Text style={styles.subtitle}>{'正在修复该问题的路上, \n很抱歉给您带来了不便'}</Text>
                    <View style={styles.btnview}>
                        <TouchableOpacity style={styles.btn} onPress={this.restart}>
                            <Text style={styles.btntxt}>重启App</Text>
                        </TouchableOpacity>
                    </View>
                    {showErrorMsg && (
                        <View style={styles.errview}>
                            <Text style={styles.errmsg}>{errorMsg}</Text>
                        </View>
                    )}
                </View>
            </ScrollView>
        );
    }
}

const styles = StyleSheet.create({
    scrlview: {
        flex: 1,
        backgroundColor: '#fff'
    },
    sclcontent: {
        height: '100%',
        backgroundColor: '#fff'
    },
    content: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center'
    },
    erricon: {
        width: 150,
        height: 150
    },
    title: {
        fontSize: 16,
        fontWeight: 'bold',
        marginTop: 20
    },
    subtitle: {
        fontSize: 14,
        color: '#666',
        textAlign: 'center',
        marginTop: 10,
        lineHeight: 18
    },
    btnview: {
        flexDirection: 'row',
        alignItems: 'center',
        marginTop: 50
    },
    btn: {
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: '#0D80FC',
        width: 150,
        height: 45,
        borderRadius: 5
    },
    btntxt: {
        fontSize: 16,
        color: 'white',
        fontWeight: 'bold'
    },
    errbtn: {
        marginTop: 20
    },
    errbtntxt: {
        fontSize: 12,
        color: '#0D80FC'
    },
    errview: {
        width: '90%',
        marginTop: 20,
        padding: 10,
        backgroundColor: '#f2f2f2'
    },
    errmsg: {
        fontSize: 14,
        color: '#333',
        lineHeight: 18
    }
});
